﻿using System;
using System.Collections.Generic;
using System.ComponentModel;

using RexToy.IoC;
using RexToy.UI.WinForm;
using RexToy.UI.WinForm.Pmlx;
using RexToy.UI.WinForm.ViewModel;

using Studio.Common;
using Studio.Model;

namespace Studio.ViewModel
{
    public class FrmMainVM : ViewModelBase
    {
        private IDatabaseModel _dbModel = DatabaseModel.CreateModel(Database.SQLServer);
        private List<FrmTemplateDesignerVM> _designerVMs;
        public FrmMainVM()
        {
            _designerVMs = new List<FrmTemplateDesignerVM>();
        }

        public IUICommand DesignerCommand { get; set; }
        public IUICommand ConnectCommand { get; set; }
        public IUICommand AboutCommand { get; set; }

        private IUICommand _exitCmd;
        public IUICommand ExitCommand
        {
            get
            {
                if (_exitCmd == null)
                {
                    _exitCmd = new ActionCommand(() => this.OnClose());
                }
                return _exitCmd;
            }
        }

        private IUICommand _disconnectCmd;
        public IUICommand DisconnectCommand
        {
            get
            {
                if (_disconnectCmd == null)
                {
                    _disconnectCmd = new ActionCommand(() => this.OnDisconnectExecute(), () => this.OnDisconnectCanExecute());
                }
                return _disconnectCmd;
            }
        }

        public bool OnConnectCanExecute()
        {
            return !_connected;
        }

        private void OnDisconnectExecute()
        {
            this._connected = false;
            this._dialect = string.Empty;
            this._msg = string.Empty;

            foreach (var designerVM in _designerVMs)
            {
                designerVM.SetDbContext(null);
            }

            RaiseConnectChange();
            _dbModel = DatabaseModel.CreateModel(Database.SQLServer);
        }

        private bool OnDisconnectCanExecute()
        {
            return _connected;
        }

        internal void Connect(bool connected, string dialect, string message, IDatabaseModel dbModel)
        {
            this._connected = connected;
            this._dialect = dialect;
            this._msg = message;            
            RaiseConnectChange();

            if (connected)
            {
                _dbModel = dbModel;
                dbModel.ReadModel();

                //var arg = new BroadcastEventArgs();
                //arg.Payload = dbModel;

                foreach (var designerVM in _designerVMs)
                {
                    designerVM.SetDbContext(dbModel);
                }
            }
        }

        private string _connectTestResult;
        public string ConnectTestResult
        {
            get { return _connectTestResult; }
        }

        internal void TestConnect(string result)
        {
            _connectTestResult = result;
            this.OnPropertyChange<FrmMainVM>(vm => vm.ConnectTestResult);
        }

        private void RaiseConnectChange()
        {
            this.OnPropertyChange<FrmMainVM>(vm => vm.Connected);
            this.OnPropertyChange<FrmMainVM>(vm => vm.Dialect);
            this.OnPropertyChange<FrmMainVM>(vm => vm.Message);
        }

        private string _msg;
        public string Message
        {
            get { return _msg; }
        }

        private bool _connected;
        public bool Connected
        {
            get { return _connected; }
        }

        private string _dialect;
        public string Dialect
        {
            get { return _dialect; }
        }

        public void AppendDesigner(FrmTemplateDesignerVM vm)
        {
            this._designerVMs.Add(vm);
            vm.SetMainVM(this);

            vm.SetDbContext(_dbModel);
        }

        public void RemoveDesigner(FrmTemplateDesignerVM vm)
        {
            this._designerVMs.Remove(vm);
        }
    }
}
